﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Controls;
using YArchitech.LIB;

namespace PressureReducOrificeCal
{
	public partial class FrmPressReducOrificeCal : System.Windows.Forms.Form
	{
		public FrmPressReducOrificeCal(Autodesk.Revit.DB.Document doc)
		{
			this.InitializeComponent();
			new YJKProcessTools().ShowInTaskbarChange(this);
			//base.Icon = Resource.YArchitechIcon;
			this.doc = doc;
			this.LoadInitializeData();
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			base.DialogResult = DialogResult.Cancel;
		}

		private void btnExplain_Click(object sender, EventArgs e)
		{
			YJKMessageBox.Show("有关减压板孔设置说明\n\r\n\r  1、应设置在直径不小于50mm的水平段上，前后管段的长度均不宜小于该管道直径的5倍；\n\r  2、孔口直径不应小于该管段直径的30%，且不应小于 20mm；\n\r  3、应采用不锈钢板材制作。");
		}

		private void btnCalculate_Click(object sender, EventArgs e)
		{
			if (this.InitializeParam())
			{
				if (this.rdoReducPressure.Checked)
				{
					this.GetOrificeDiameterVal();
					return;
				}
				this.GetReducePressureVal();
			}
		}

		private void rdoReducPressure_CheckedChanged(object sender, EventArgs e)
		{
			if (this.rdoReducPressure.Checked)
			{
				this.txtPipeDiameter.Text = "150";
				this.txtFlow.Text = "25";
				this.txtReducePressure.Text = "10";
				this.txtOrificeDiameter.Text = "";
				this.txtOrificeDiameter.Enabled = false;
				this.txtReducePressure.Enabled = true;
				return;
			}
			this.txtPipeDiameter.Text = "150";
			this.txtFlow.Text = "25";
			this.txtOrificeDiameter.Text = "60";
			this.txtReducePressure.Text = "";
			this.txtOrificeDiameter.Enabled = true;
			this.txtReducePressure.Enabled = false;
		}

		private bool InitializeParam()
		{
			if (!int.TryParse(this.txtPipeDiameter.Text, out this.pipeDiameter) || this.pipeDiameter < 50)
			{
				this.txtPipeDiameter.Focus();
				YJKMessageBox.Show("请输入有效的管径数值!");
				return false;
			}
			if (!double.TryParse(this.txtFlow.Text, out this.flow) || this.flow <= 0.0)
			{
				this.txtFlow.Focus();
				YJKMessageBox.Show("请输入有效的流量数值!");
				return false;
			}
			if (this.rdoReducPressure.Checked)
			{
				if (!double.TryParse(this.txtReducePressure.Text, out this.reducePressure) || this.pipeDiameter <= 0 || this.reducePressure <= 0.0)
				{
					this.txtReducePressure.Focus();
					YJKMessageBox.Show("请输入有效的压力数值!");
					return false;
				}
			}
			else if (!double.TryParse(this.txtOrificeDiameter.Text, out this.orificeDiameter) || this.orificeDiameter <= 0.0)
			{
				this.txtOrificeDiameter.Focus();
				YJKMessageBox.Show("请输入有效的孔板直径数值!");
				return false;
			}
			return true;
		}

		private void GetOrificeDiameterVal()
		{
			double num = Convert.ToDouble(this.reducePressure) / 100.0;
			double num2 = Convert.ToDouble(this.flow) / 1000.0;
			double num3 = Convert.ToDouble(this.pipeDiameter) / 1000.0;
			double x = 4.0 * num2 / (Math.PI * num3 * num3);
			double num4 = this.dicDi.FirstOrDefault((KeyValuePair<int, double> p) => p.Key == this.pipeDiameter).Value / 1000.0;
			if (num4 == 0.0)
			{
				YJKMessageBox.Show("请输入有效的管径数值!");
				return;
			}
			double num5 = Math.Pow(num * 2.0 * 9.81 / (Math.Pow(x, 2.0) * 0.01), 0.5) + 1.0;
			double num6 = -(1.75 + 1.175 * num5);
			double num7 = 1.9250000000000003;
			double num8 = (-num6 + Math.Pow(Math.Pow(num6, 2.0) - 4.0 * num5 * num7, 0.5)) / (2.0 * num5);
			double num9 = Math.Pow((-num6 - Math.Pow(Math.Pow(num6, 2.0) - 4.0 * num5 * num7, 0.5)) / (2.0 * num5) * Math.Pow(num4, 2.0), 0.5);
			this.txtOrificeDiameter.Text = Math.Round(num9 * 1000.0, 3).ToString();
		}

		private void GetReducePressureVal()
		{
			double num = Convert.ToDouble(this.flow) / 1000.0;
			double num2 = Convert.ToDouble(this.pipeDiameter) / 1000.0;
			double num3 = Convert.ToDouble(this.orificeDiameter + 1.0) / 1000.0;
			double x = 4.0 * num / (Math.PI * num2 * num2);
			double num4 = this.dicDi.FirstOrDefault((KeyValuePair<int, double> p) => p.Key == this.pipeDiameter).Value / 1000.0;
			if (num4 == 0.0)
			{
				YJKMessageBox.Show("请输入有效的管径数值!");
				return;
			}
			double num5 = Math.Pow(1.75 * Math.Pow(num4, 2.0) * (1.1 - Math.Pow(num3 / num4, 2.0)) / (Math.Pow(num3, 2.0) * (1.175 - Math.Pow(num3 / num4, 2.0))) - 1.0, 2.0);
			double num6 = 0.01 * num5 * Math.Pow(x, 2.0) / 19.62;
			this.txtReducePressure.Text = Math.Round(num6 * 100.0, 3).ToString();
		}

		private void LoadInitializeData()
		{
			this.dicDi.Clear();
			PipeSegment pipeSegmentByPipeTypeName = this.GetPipeSegmentByPipeTypeName("内外热镀锌钢管");
			if (pipeSegmentByPipeTypeName != null)
			{
				IEnumerator<MEPSize> enumerator = pipeSegmentByPipeTypeName.GetSizes().GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						MEPSize mepsize = enumerator.Current;
						this.dicDi.Add(Convert.ToInt32(Math.Ceiling(304.8 * mepsize.NominalDiameter)), 304.8 * mepsize.InnerDiameter);
					}
					return;
				}
			}
			this.dicDi.Add(15, 14.75);
			this.dicDi.Add(20, 20.25);
			this.dicDi.Add(25, 26.0);
			this.dicDi.Add(32, 34.75);
			this.dicDi.Add(40, 40.0);
			this.dicDi.Add(50, 52.0);
			this.dicDi.Add(65, 67.0);
			this.dicDi.Add(80, 79.5);
			this.dicDi.Add(100, 105.0);
			this.dicDi.Add(125, 130.0);
			this.dicDi.Add(150, 155.0);
			this.dicDi.Add(175, 173.0);
			this.dicDi.Add(200, 198.0);
			this.dicDi.Add(225, 224.0);
			this.dicDi.Add(250, 252.0);
			this.dicDi.Add(275, 278.0);
			this.dicDi.Add(300, 305.0);
			this.dicDi.Add(325, 331.0);
			this.dicDi.Add(350, 357.0);
		}

		public PipeSegment GetPipeSegmentByPipeTypeName(string pipeTypeName)
		{
			PipeType pipeTypeByTypeName = this.GetPipeTypeByTypeName(pipeTypeName);
			if (pipeTypeByTypeName == null)
			{
				return null;
			}
			RoutingPreferenceManager routingPreferenceManager = pipeTypeByTypeName.RoutingPreferenceManager;
			return this.doc.GetElement(routingPreferenceManager.GetRule((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)0, 0).MEPPartId) as PipeSegment;
		}

		public PipeType GetPipeTypeByTypeName(string typeName)
		{
			return new FilteredElementCollector(this.doc).OfClass(typeof(PipeType)).ToElements().FirstOrDefault((Element p) => p.Name.Contains(typeName)) as PipeType;
		}

		private int pipeDiameter;

		private double flow;

		private double reducePressure;

		private double orificeDiameter;

		private Dictionary<int, double> dicDi = new Dictionary<int, double>();

		private Document doc;
	}
}
